package com.zmn.plat.business.impl.pilot;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.plat.business.interfaces.pilot.ServCityPriceBService;
import com.zmn.plat.manager.dictionary.OnePriceDict;
import com.zmn.plat.model.entity.area.BaseArea;
import com.zmn.plat.model.entity.pilot.ServCityPrice;
import com.zmn.plat.model.entity.pilot.ServCityPriceAddEditVO;
import com.zmn.plat.model.entity.pilot.ServCityPriceLog;
import com.zmn.plat.model.entity.pilot.ServCityPriceQuery;
import com.zmn.plat.services.interfaces.area.BaseAreaService;
import com.zmn.plat.services.interfaces.pilot.ServCityPriceLogService;
import com.zmn.plat.services.interfaces.pilot.ServCityPriceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 城市试点业务层
 *
 * @author yangshuangping
 * @since 2021-6-28 16:41:54
 */
@Service
@Slf4j
public class ServCityPriceBServiceImpl implements ServCityPriceBService {

    @Autowired
    private ServCityPriceService priceService;

    @Autowired
    private ServCityPriceLogService logService;

    @Autowired
    private BaseAreaService areaService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Integer> addEdit(ServCityPriceAddEditVO vo) {
        List<Integer> relationIds = new ArrayList<>();
        try {
            vo.getCityList().forEach(item -> {
                String[] split = item.split("-");
                if (split.length < 2) {
                    throw new IllegalArgumentException("param cityList is error");
                }
                int provinceId = Integer.valueOf(split[0]);
                Integer cityId = split[1].equals("0") ? null : Integer.valueOf(split[1]);
                String provinceName;
                String cityName = null;
                if (provinceId == 0 && cityId == 0) {
                    // 全国
                    provinceName = "全国";
                } else if (cityId == null) {
                    // 全省
                    BaseArea province = areaService.findByKey(provinceId);
                    provinceName = province.getName();
                } else {
                    // 全市
                    BaseArea province = areaService.findByKey(provinceId);
                    BaseArea city = areaService.findByKey(cityId);

                    provinceName = Optional.ofNullable(province).map(p -> p.getName()).orElse(null);
                    cityName = Optional.ofNullable(city).map(p -> p.getName()).orElse(null);
                }

                ServCityPriceQuery priceQuery = new ServCityPriceQuery();
                priceQuery.setProvinceId(provinceId);
                priceQuery.setCityId(cityId);
                priceQuery.setType(vo.getType());
                List<ServCityPrice> servCityPrices = priceService.listByQuery(priceQuery);

                Integer relationId;

                // 检查是否存在该城市配置
                if (servCityPrices == null || servCityPrices.size() == 0) {
                    // 不存在新增
                    ServCityPrice servCityPrice = new ServCityPrice();
                    servCityPrice.setType(vo.getType());
                    servCityPrice.setPayType(vo.getPayType());
                    servCityPrice.setStatus(vo.getStatus());
                    servCityPrice.setProvinceId(provinceId);
                    servCityPrice.setCityId(cityId);
                    servCityPrice.setProvinceName(provinceName);
                    servCityPrice.setCityName(cityName);

                    servCityPrice.setDepositStatus(vo.getDepositStatus());
                    Integer amountFen = Objects.isNull(vo.getDeposit()) ? 0 : vo.getDeposit();
                    servCityPrice.setDeposit(amountFen);

                    servCityPrice.setDepositDeductionStatus(vo.getDepositDeductionStatus());
                    servCityPrice.setDepositDeductionAmount(vo.getDepositDeductionAmount());

                    // 新增时填充操作人
                    servCityPrice.setCreater(vo.getOperatorName());
                    servCityPrice.setUpdater(vo.getOperatorName());

                    priceService.insert(servCityPrice);
                    relationId = servCityPrice.getRelationId();
                    // 操作日志
                    saveLog(String.format("新增执行城市: %s", cityName), relationId, vo);
                } else {
                    // 存在城市修改
                    ServCityPrice dbCityPrice = servCityPrices.get(0);
                    relationId = dbCityPrice.getRelationId();
                    ServCityPrice servCityPrice = new ServCityPrice();
                    servCityPrice.setRelationId(relationId);
                    servCityPrice.setPayType(vo.getPayType());
                    servCityPrice.setStatus(vo.getStatus());
                    servCityPrice.setProvinceName(provinceName);
                    servCityPrice.setCityName(cityName);

                    // 更新人，更新时间修改
                    servCityPrice.setUpdater(vo.getOperatorName());
                    servCityPrice.setUpdateTime(DateUtil.getNow());
                    // NumberUtil.convertMoneyToFen()
                    Integer amountFen = Objects.isNull(vo.getDeposit()) ? null : vo.getDeposit();

                    servCityPrice.setDeposit(amountFen);
                    servCityPrice.setDepositStatus(vo.getDepositStatus());

                    servCityPrice.setDepositDeductionStatus(vo.getDepositDeductionStatus());
                    servCityPrice.setDepositDeductionAmount(vo.getDepositDeductionAmount());

                    //支付方式不为“下单必须支付”清空定金状态
                    if (!Objects.equals(servCityPrice.getPayType(), GlobalConsts.NO)) {
                        servCityPrice.setDepositStatus(null);
                    }
                    saveLog(getChangeContent(dbCityPrice, servCityPrice), servCityPrice.getRelationId(), vo);
                    priceService.updateByKey(servCityPrice);
                }
                relationIds.add(relationId);
            });
            return relationIds;
        } catch (Exception e) {
            log.error("保存失败.", e);
        }
        return null;
    }

    /**
     * 保存日志
     *
     * @param changeContent 内容
     * @param relationId    配置id
     * @param vo            创建人
     */
    private void saveLog(String changeContent, Integer relationId, ServCityPriceAddEditVO vo) {
        if (StringUtil.isNotBlank(changeContent)) {
            // 操作日志
            ServCityPriceLog priceLog = new ServCityPriceLog();
            priceLog.setRelationId(relationId);
            priceLog.setAbutmenterType((byte) 1);
            priceLog.setAbutmenterId(vo.getOperatorId());
            priceLog.setAbutmenter(vo.getOperatorName());
            priceLog.setCreateTime(DateUtil.getNow());
            priceLog.setContent(changeContent);
            logService.insert(priceLog);
        }
    }

    /**
     * 变更操作内容
     *
     * @param dbCityPrice
     * @param servCityPrice
     * @return
     */
    private String getChangeContent(ServCityPrice dbCityPrice, ServCityPrice servCityPrice) {
        StringBuilder sb = new StringBuilder();
        if (!Objects.equals(dbCityPrice.getPayType(), servCityPrice.getPayType())) {
            String changePayType = String.format("变更支付方式: \"%s\" -> \"%s\""
                    , OnePriceDict.getPayType(dbCityPrice.getPayType()), OnePriceDict.getPayType(servCityPrice.getPayType()));
            sb.append(changePayType);
        }
        if (!Objects.equals(dbCityPrice.getStatus(), servCityPrice.getStatus())) {
            String changeStatus = String.format("变更状态: \"%s\" -> \"%s\""
                    , OnePriceDict.getStatus(dbCityPrice.getStatus()), OnePriceDict.getStatus(servCityPrice.getStatus()));
            if (sb.length() > 0) {
                sb.append("</br>");
            }
            sb.append(changeStatus);
        }
        return sb.toString();
    }

}
